import sys
import os
import json
import traceback
import potx
import requests

from loguru import logger
from PyQt5.QtGui import QIcon, QFont, QDesktopServices, QPixmap, QPainter
from PyQt5.QtCore import pyqtSignal, QThread, QUrl, QRect, QSize
from PyQt5.QtWidgets import  QFileDialog, QWidget, QLabel, QVBoxLayout, QMessageBox, QTextEdit, QPushButton
from qfluentwidgets import FluentWindow, ComboBox, BodyLabel, LineEdit, PrimaryPushButton, NavigationInterface, \
    NavigationItemPosition, QColor, ProgressBar


class HomePage(QWidget):
    def __init__(self):
        super().__init__()
        self.background_image = QPixmap("background.jpg")  # 加载背景图片
        self.image_position = QRect(100, 50, 950, 483)

    def paintEvent(self, event):
        # 重写 paintEvent 方法，绘制背景图片
        painter = QPainter(self)
        painter.drawPixmap(self.image_position,
                           self.background_image.scaled(self.image_position.size(), aspectRatioMode=True))


class MyWindow(FluentWindow):
    def __init__(self, card_key):
        super().__init__()
        # self.config = config
        self.initUI()
        self.card_key = card_key
        self.server_url = "http://127.0.0.1:5000/api/reducecount"

    def initUI(self):
        self.setWindowTitle("文字识别工具")
        self.setGeometry(360, 80, 1200, 800)

        # 创建首页页面
        # self.home_page = HomePage()
        # # self.home_page = QWidget()
        # self.home_page.setObjectName("home_page")
        # self.init_home_page()
        # self.addSubInterface(self.home_page, QIcon(self.resource_path("background.jpg")), "首页",
        #                      position=NavigationItemPosition.TOP)
        # 创建功能页面
        self.function_page = QWidget()
        self.function_page.setObjectName("function_page")  # 设置 objectName
        self.init_function_page()
        self.addSubInterface(self.function_page, QIcon(self.resource_path("home.png")), "功能页面",
                             position=NavigationItemPosition.TOP)

        # 创建配置页面
        self.config_page = ConfigPage()
        self.config_page.setObjectName("config_page")
        self.addSubInterface(self.config_page, QIcon(self.resource_path("config.png")), "设置页面",
                             position=NavigationItemPosition.TOP)

        # 初始化导航栏
        self.navigationInterface.setCurrentItem("home")

    # def init_home_page(self):
    #     self.setWindowTitle("文字识别工具")
    #     # 创建可点击的标签
    #     self.click_to_web('<a href="https://www.example.com">使用说明书</a>', 100, 35)
    #     self.click_to_web('<a href="https://www.example.com">常见问题</a>', 185, 35)
    #     self.click_to_web('<a href="https://www.example.com">联系我们</a>', 260, 35)
    #
    #     # 创建跳转到功能页面的按钮
    #     self.create_jump_button("点击我去识别", 100, 580, 100, 600, self.jump_to_function_page, "to_function.jpg")
    #     # 创建跳转到配置页面的按钮 去配置
    #     self.create_jump_button("点击我去配置", 400, 580, 400, 600, self.jump_to_config_page, "to_config.jpg")

    def click_to_web(self, url, x, y):
        link_label = QLabel(url, self.home_page)
        link_label.setOpenExternalLinks(False)
        link_label.move(x, y)
        link_label.linkActivated.connect(self.open_link)

    def create_jump_button(self, text, label_x, label_y, button_x, button_y, clicked_func, icon_path):
        label = BodyLabel(text, self.home_page)
        label.move(label_x, label_y)
        label.setTextColor(QColor(0, 150, 0), QColor(255, 0, 0))
        button = QPushButton("", self.home_page)
        button.move(button_x, button_y)
        button.clicked.connect(clicked_func)
        icon = QIcon(icon_path)
        button.setIcon(icon)
        button.setIconSize(QSize(150, 60))

    def resource_path(self, relative_path):
        """ 获取资源绝对路径，用于 PyInstaller 打包后的资源访问 """
        if hasattr(sys, '_MEIPASS'):
            # PyInstaller 解压后的临时路径
            return os.path.join(sys._MEIPASS, relative_path)
        return relative_path  # 开发环境下保持原样

    def init_function_page(self):
        comboBox = ComboBox(self.function_page)
        items = ['增值税发票识别', '银行单据识别', '身份证识别', '商业许可证识别', '行驶证识别', '驾驶证识别', '通用识别', '银行卡识别']
        self.selected_text = "增值税发票识别"   # 默认选中项
        comboBox.addItems(items)
        comboBox.move(80, 60)
        comboBox.resize(200, 30)
        comboBox.currentIndexChanged.connect(self.on_comboBox_changed)

        LabelUtils.create_label("文件夹", self.function_page, 80, 130)  # 文件夹标签
        self.input_line_edit = LineEditUtils.create_line_edit(
            self.function_page, 200, 130, "", 670)  # 文件夹输入框

        ButtonUtils.create_button("选择文件", self.function_page, 890, 130, 100, 30, self.input_file)
        ButtonUtils.create_button("选择文件夹", self.function_page, 1000, 130, 100, 30, self.input_dir)

        LabelUtils.create_label("结果目录", self.function_page, 80, 180)  # 结果目录标签
        self.output_line_edit = LineEditUtils.create_line_edit(
            self.function_page, 200, 180, "", 670)  # 结果目录输入框

        ButtonUtils.create_button("选择结果目录", self.function_page, 890, 180, 210, 30, self.output_dir)

        # 日志
        LabelUtils.create_label("运行状态", self.function_page, 80, 280)
        self.run_log_text = QTextEdit(self.function_page)
        self.run_log_text.setObjectName("日志")
        self.run_log_text.move(200, 280)
        self.run_log_text.resize(900, 300)

        # 进度条
        LabelUtils.create_label("进度条", self.function_page, 80, 600)
        self.progress_bar = ProgressBar(self.function_page)
        self.progress_bar.move(200, 610)
        self.progress_bar.resize(900, 50)
        self.progress_bar.setRange(0, 80)
        self.progress_bar.setValue(0)

        # 提交按钮
        self.submit_button = ButtonUtils.create_button("开始识别", self.function_page, 80, 650, 100, 30, self.submit_file)

        # 打开输出结果目录按钮
        self.open_result_button = ButtonUtils.create_button("打开结果目录", self.function_page, 250, 650, 680, 30, self.open_result_dir)

        # 关闭按钮
        self.close_button = ButtonUtils.create_button("关闭", self.function_page, 1000, 650, 100, 30, self.close)

    def jump_to_function_page(self):
        # 跳转到功能页面
        self.navigationInterface.setCurrentItem("function_page")
        self.stackedWidget.setCurrentWidget(self.function_page)  # 更新主页面

    def jump_to_config_page(self):
        # 跳转到功能页面
        self.navigationInterface.setCurrentItem("config_page")
        self.stackedWidget.setCurrentWidget(self.config_page)  # 更新主页面

    def open_link(self, link):
        # 使用 QDesktopServices 打开链接
        QDesktopServices.openUrl(QUrl(link))

    def on_comboBox_changed(self):
        # 获取当前选中的文字
        self.selected_text = self.sender().currentText()

    def input_dir(self):
        file_path = QFileDialog.getExistingDirectory(self, "选择输入文件目录")
        self.input_line_edit.setText(file_path)

    def input_file(self):
        file, _ = QFileDialog.getOpenFileName(self, "选择文件")
        if file:
            self.input_line_edit.setText(file)

    def output_dir(self):
        file_path = QFileDialog.getExistingDirectory(self, "选择输出结果目录")
        self.output_line_edit.setText(file_path)

    def open_result_dir(self):
        file_path = self.output_line_edit.text()
        path = file_path.replace("/", "\\")
        os.system(f"start explorer {path}")

    def submit_file(self):
        input_path = self.input_line_edit.text()
        output_path = self.output_line_edit.text()
        if input_path == "":
            QMessageBox.warning(self, "警告", "请选择文件目录")
            return
        elif output_path == "":
            QMessageBox.warning(self, "警告", "请选择结果目录")
            return

        config_path = f"{os.path.dirname(__file__)}/sysConfig.json"
        print(config_path)
        config = json.load(open(config_path, 'r', encoding="utf-8"))

        api_key = config["api_key"]
        secret_key = config["secret_key"]
        update_json(str(config_path), "input_path", input_path)
        update_json(str(config_path), "output_path", output_path)

        if not api_key or not secret_key:
            reply = QMessageBox.warning(self, "警告", "配置信息未配置！")
            if reply:
                return

        self.submit_button.setEnabled(False)
        self.open_result_button.setEnabled(False)
        self.close_button.setEnabled(False)

        self.run_log_text.setText("")
        self.progress_bar.setValue(0)
        config["input_path"] = self.input_line_edit.text()
        config["output_path"] = self.output_line_edit.text()

        os.system('taskkill /IM EXCEL.exe /F')
        os.system('taskkill /IM WPS.exe /F')

        '''
        开始转换
        '''
        self.progress_txt = ""
        self.process_thread = transferThread(self.selected_text)
        self.process_thread.start()
        self.process_thread.start_process_signal.connect(self.processStatus)
        try:
            resp = requests.post(f"{self.server_url}", json={'card_key': self.card_key}, timeout=5)
            result = resp.json()
            if result.get('success'):
                self.process_thread.exec_()
                return
            else:
                if result.get('message') == '时间卡密不需要扣减次数':
                    self.process_thread.exec_()
                    return
                else:
                    QMessageBox.warning(self, '扣减失败', result.get('message', '生成失败'))
        except requests.exceptions.RequestException:
            QMessageBox.critical(self, "网络异常", "网络异常，请检查网络后重试！")
            return
        except Exception:
            QMessageBox.warning(self, "扣减失败", "扣减次数失败！")

        self.process_thread.exec_()

        '''
        处理子线程信号函数
        '''

    def processStatus(self, value, string):
        self.progress_txt = f"{self.progress_txt}\n{string}"
        if string == "":
            self.progress_bar.setMaximum(int(value))
            self.max_value = int(value)
        else:
            self.progress_bar.setValue(int(value))
            self.run_log_text.setText(self.progress_txt)
            if string.find("Error") >= 0:
                reply = QMessageBox.warning(self, "错误", f"错误：{string}！")
                if reply:
                    self.submit_button.setEnabled(True)
                    self.open_result_button.setEnabled(True)
                    self.close_button.setEnabled(True)
                    return
            elif int(value) == self.max_value and string.find("识别全部完成") >= 0:
                reply = QMessageBox.warning(self, "成功", "处理已完成！")
                if reply:
                    self.submit_button.setEnabled(True)
                    self.open_result_button.setEnabled(True)
                    self.close_button.setEnabled(True)
                    return


class ConfigPage(QWidget):
    def __init__(self):
        super().__init__()
        self.initUI()

    def initUI(self):
        config_page = QWidget(self)
        config_page.setObjectName("config_page")  # 设置 objectName

        # api_key 标签
        LabelUtils.create_label("api_key", config_page, 80, 180)

        # api_key 输入框
        self.api_key_edit = LineEditUtils.create_line_edit(config_page, 200, 180, "请输入你的腾讯 OCR 的 api_key", 780)

        # secret_key 标签
        LabelUtils.create_label("secret_key", config_page, 80, 230)

        # secret_key 输入框
        self.secret_key_edit = LineEditUtils.create_line_edit(config_page, 200, 230, "请输入你的腾讯 OCR 的 secret_key",
                                                              780)

        # 保存按钮
        ButtonUtils.create_button("保存", config_page, 80, 300, 100, 30, self.save_file)

    def save_file(self):
        api_key = self.api_key_edit.text()
        secret_key = self.secret_key_edit.text()

        config_path = f"{os.path.dirname(__file__)}/sysConfig.json"

        update_json(str(config_path), "api_key", api_key)
        update_json(str(config_path), "secret_key", secret_key)
        reply = QMessageBox.warning(self, "成功", "保存成功！")
        if reply:
            return

class LabelUtils:
    """创建标签"""
    @staticmethod
    def create_label(text, parent, x, y):
        secret_key_label = BodyLabel(text, parent)
        secret_key_label.move(x, y)
        secret_key_label.setTextColor(QColor(0, 150, 0), QColor(255, 0, 0))
        secret_key_label.setFont(QFont("Arial", 15))


class LineEditUtils:
    """创建输入框"""
    @staticmethod
    def create_line_edit(parent, x, y, placeholder_text, width):
        line_edit = LineEdit(parent)
        line_edit.move(x, y)
        line_edit.setText(placeholder_text)
        line_edit.setFixedWidth(width)
        return line_edit

class ButtonUtils:
    """创建按钮"""
    @staticmethod
    def create_button(text, parent, x, y, width, height, connect_func):
        button = PrimaryPushButton(text, parent)
        button.move(x, y)
        button.resize(width, height)
        button.clicked.connect(connect_func)
        return button


def update_json(jsonFile, key, value):
    try:
        with open(jsonFile, 'r', encoding="utf-8") as fr:  # 文件路径自己改成完整的
            json_all = json.load(fr)
            json_all[key] = value
        with open(jsonFile, 'w+', encoding="utf-8") as fw:
            json.dump(json_all, fw, ensure_ascii=False, indent=4)
    except:
        error = traceback.format_exc()
        logger.error(error)


class transferThread(QThread):
    '''
    创建信号 接受字符串（这里用于主线程向子线程传递信息）
    '''
    start_process_signal = pyqtSignal(int, str)

    def __init__(self, selected_text):
        super(transferThread, self).__init__()
        self.selected_text = selected_text

    '''
    子线程主处理函数
    '''

    def run(self):
        try:
            self.start_process_signal.emit(3, "")

            config_path = f"{os.path.dirname(__file__)}/sysConfig.json"

            config = json.load(open(config_path, 'r', encoding="utf-8"))
            input_path = config["input_path"]
            output_path = config["output_path"]
            api_key = config["api_key"]
            secret_key = config["secret_key"]

            result_file = "识别结果.xlsx"
            self.start_process_signal.emit(1, "开始识别")

            if self.selected_text == "增值税发票识别":
                potx.ocr2excel.VatInvoiceOCR2Excel(input_path=input_path, output_path=output_path,
                                                   output_excel=result_file, id=api_key, key=secret_key)
            elif self.selected_text == "银行单据识别":
                potx.ocr2excel.BankSlipOCR2Excel(input_path=input_path, output_path=output_path,
                                                 output_excel=result_file, id=api_key, key=secret_key)
            elif self.selected_text == "身份证识别":
                potx.ocr2excel.IDCardOCR2Excel(input_path=input_path, output_path=output_path, output_excel=result_file,
                                               id=api_key, key=secret_key)
            elif self.selected_text == "商业许可证识别":
                potx.ocr2excel.BizLicenseOCR2Excel(input_path=input_path, output_path=output_path,
                                                   output_excel=result_file, id=api_key, key=secret_key)
            elif self.selected_text == "行驶证识别":
                potx.ocr2excel.VehicleLicenseOCR2Excel(input_path=input_path, output_path=output_path,
                                                       output_excel=result_file, id=api_key, key=secret_key)
            elif self.selected_text == "驾驶证识别":
                potx.ocr2excel.DriverLicenseOCR2Excel(input_path=input_path, output_path=output_path,
                                                      output_excel=result_file, id=api_key, key=secret_key)
            elif self.selected_text == "通用识别":
                potx.ocr2excel.RecognizeGeneralInvoiceOCR2Excel(input_path=input_path, output_path=output_path,
                                                                output_excel=result_file, id=api_key, key=secret_key)
            elif self.selected_text == "银行卡识别":
                potx.ocr2excel.LicensePlateOCR2Excel(input_path=input_path, output_path=output_path,
                                                     output_excel=result_file, id=api_key, key=secret_key)
            self.start_process_signal.emit(2, "识别完成！")
            self.start_process_signal.emit(3, "识别全部完成！")

        except:
            msg = traceback.format_exc()
            self.start_process_signal.emit(1, f"Error:{msg}")